package ingeslotenstenen;

import java.util.Scanner;
import ui.OthelloUserInterface;
import ui.UIHulpMethodes;
import ui.UserInterfaceFactory;
import ui.Event;

public class Orthello {

	OthelloUserInterface ui;
	private BeurtRij beurtRij;
	private BordRij bordRij;
	private final static int MAX_AANTAL_BEURTEN = 120;
	private final static int HOOGTE = 8;
	private final static int BREEDTE= 8;
	private int huidigeBeurt;
	private Richting richting;
	Orthello(){
		UserInterfaceFactory.zetLageResolutie(true);
		beurtRij = new BeurtRij(MAX_AANTAL_BEURTEN);
		bordRij = new BordRij(MAX_AANTAL_BEURTEN);
		ui = UserInterfaceFactory.geefOthelloUI();
		UIHulpMethodes.vraagGebruikerOmInvoer();
	}

	public void plaatsOmcirkeling(CoordinaatRij coordinaatRij){
		for(int i = 0;i<coordinaatRij.geefAantalCoordinaten();i++){
			ui.plaatsOmcirkeling(coordinaatRij.geefCoordinaten()[i].geefX(),coordinaatRij.geefCoordinaten()[i].geefY());
			//ui.printf("PLAATS:%d,%d", coordinaatRij.geefCoordinaten()[i].geefX(),coordinaatRij.geefCoordinaten()[i].geefY());
		}
		ui.toon();
	}


	public CoordinaatRij checkRichting(int i,Coordinaat klikBackup,int kleur){
		CoordinaatRij tussenliggendEenRichting = new CoordinaatRij(HOOGTE*BREEDTE);
		Coordinaat klik = new Coordinaat(klikBackup.geefX(),klikBackup.geefY());
		
		Bord b = bordRij.geefBord(huidigeBeurt);
		klik.transleer(Richting.RICHTINGEN[i]);
		while(klik.geefX() < BREEDTE 		&& klik.geefY() < HOOGTE 
				&& 	klik.geefX() >= 0 		&& klik.geefY() >= 0){
			
			int kleurCheck = b.geefWaarde(klik);
			if(kleurCheck == geefInverseKleur(kleur)){
				tussenliggendEenRichting.voegToe(new Coordinaat(klik.geefX(), klik.geefY()));
			}
			else if(kleurCheck == kleur){
				if(tussenliggendEenRichting.geefAantalCoordinaten() > 0){
					return tussenliggendEenRichting;
				}
				else{
					return new CoordinaatRij(0);
				}
			}
			else if(kleurCheck == OthelloUserInterface.LEEG){
				return new CoordinaatRij(0);
			}
			else{
				
			}
			klik.transleer(Richting.RICHTINGEN[i]);
		}
		return new CoordinaatRij(0);

	}

	public CoordinaatRij checkTussenliggendeStenen(Coordinaat klik,int kleur){
		CoordinaatRij tussenliggendeStenen = new CoordinaatRij(HOOGTE*BREEDTE);
		if(bordRij.geefBord(huidigeBeurt).geefWaarde(klik) == OthelloUserInterface.LEEG){
			for(int i = 0;i < Richting.RICHTINGEN.length;i++){
				CoordinaatRij tmpCR = checkRichting(i,klik,kleur);
				tussenliggendeStenen.voegCoordinaatRijToe(tmpCR);
			}
		}
		return tussenliggendeStenen;
	}

	public Bord geefBeginBord(){
		Bord beginBord = new Bord(BREEDTE,HOOGTE);
		beginBord.voegToe(3, 3, ui.WIT);
		beginBord.voegToe(4, 4, ui.WIT);
		beginBord.voegToe(3, 4, ui.ZWART);
		beginBord.voegToe(4, 3, ui.ZWART);
		return beginBord;
	}

	public Bord plaatsCoordinaatRijOpBord(Bord bord,CoordinaatRij coordinaatRij,int kleur){
		for(int i = 0;i < coordinaatRij.geefAantalCoordinaten();i++){
			bord.voegToe(coordinaatRij.geefCoordinaten()[i], kleur);
		}
		return bord;
	}

	public Bord plaatsZetOpBord(Bord bord,Zet zet,int kleur){
		bord.voegToe(zet.geefZetCoordinaat(), kleur);
		bord = plaatsCoordinaatRijOpBord(bord,zet.geefVeranderdeStenen(),kleur);


		return bord;
	}

	public Bord plaatsBeurtOpBord(Bord bord, int zetNummer){
		Beurt beurt = beurtRij.geefBeurt(zetNummer);
		if(beurt.geefZet()){
			bord = plaatsZetOpBord(bord,beurt.geefZetInhoud(),geefKleur(beurt));
		}
		return bord;
	}

	public void verwerkInvoerTotBordRij(){
		bordRij.voegToe(geefBeginBord());
		for(int i = 0;i < beurtRij.geefHuidigAantalBeurten();i++){
			bordRij.kopieerBord(i, i + 1);
			bordRij.voegToe(plaatsBeurtOpBord(bordRij.geefBord(i + 1),i));
		}

	}

	public String geefSpelerNaam(Beurt beurt){
		if(beurt.geefWit()){
			return new String("wit");
		} else {
			return new String("zwart");
		}
	}

	public void laatBordZien(Bord bord){
		ui.maakLeeg();
		for(int i = 0;i < bord.geefLengte();i++){
			for(int j = 0;j < bord.geefHoogte();j++){
				ui.plaats(i, j, bord.geefWaarde(i, j));
			}
		}
		ui.printf("Huidige beurt: %d, %s is aan zet.\n", huidigeBeurt,geefSpelerNaam(beurtRij.geefBeurt(huidigeBeurt)));
		ui.toon();
	}

	public int geefKleur(Beurt beurt){

		//in 1 regel
		if(beurt.geefWit()){
			return ui.WIT;
		} else {
			return ui.ZWART;
		}
	}

	public int geefInverseKleur(Beurt beurt){

		//in 1 regel
		if(beurt.geefWit()){
			return ui.ZWART;
		} else {
			return ui.WIT;
		}
	}

	public int geefInverseKleur(int kleur){
		if(kleur == ui.ZWART){
			return ui.WIT;
		} else if (kleur == ui.LEEG){
			return ui.LEEG;
		} else {
			return ui.ZWART;
		}
	}


	public void verwerkCijfer(Event event){
		if(huidigeBeurt < beurtRij.geefHuidigAantalBeurten() - Integer.parseInt(event.data)){
			laatBordZien(bordRij.geefBord(huidigeBeurt + Integer.parseInt(event.data)));
			huidigeBeurt += Integer.parseInt(event.data);
		}
	}

	public void verwerkAltCijfer(int nummer){
		if(huidigeBeurt > 0 + nummer){
			laatBordZien(bordRij.geefBord(huidigeBeurt - nummer));
			huidigeBeurt -= nummer;
		}
	}

	public void verwerkLetter(Event event){
		if(event.data.equals("z") && huidigeBeurt <= beurtRij.geefHuidigAantalBeurten()){
			laatBordZien(bordRij.geefBord(huidigeBeurt));
			huidigeBeurt += 1;
		} else if (event.data.equals("x") && huidigeBeurt > 1){
			laatBordZien(bordRij.geefBord(huidigeBeurt - 2));
			huidigeBeurt -= 1;
		} else if (event.data.equals("a") || event.data.equals("b") || event.data.equals("c") || event.data.equals("d") || event.data.equals("e") || event.data.equals("f") || event.data.equals("g") || event.data.equals("h") || event.data.equals("i")){
			int nummer = (event.data.charAt(0) - 'a' + 1);
			verwerkAltCijfer(nummer);
		}

	}

	public void verwerkKlik(Event event){
		//ui.printf("KLIK!");
		laatBordZien(bordRij.geefBord(huidigeBeurt));
		Scanner klik = new Scanner(event.data);
		Coordinaat coordinaat = leesCoordinaat(klik.next().charAt(0),klik.nextInt());
		int kleur = geefKleur(beurtRij.geefBeurt(huidigeBeurt));
		CoordinaatRij ringen =  checkTussenliggendeStenen(coordinaat,kleur);
		if(ringen.geefAantalCoordinaten() > 0){
			ui.plaatsDoorzichtig(coordinaat.geefX(),coordinaat.geefY(), kleur);
		}
		//ui.printf("%d\t%d\t%d\n", coordinaat.geefX(),coordinaat.geefY(),kleur);
		
		plaatsOmcirkeling(ringen);
	}

	public void verwerkEvent(Event event){
		if(event.naam.equals("letter")){
			verwerkLetter(event);
		} else if (event.naam.equals("alt_cijfer")){
			//verwerkAltCijfer(event);
		} else if (event.naam.equals("cijfer")){
			verwerkCijfer(event);
		} else if (event.naam.equals("klik")){
			verwerkKlik(event);
		}

	}

	public void wachtOpInvoer(){
		while(true){
			Event event = ui.geefEvent();
			verwerkEvent(event);
		}
	}

	public boolean leesZet(String input){
		return input.contains("zet");
	}

	public boolean leesWitOfZwart(String input){
		return input.contains("wit");
	}

	public Coordinaat leesCoordinaat(char letter,int cijfer){
		letter -= 'a';
		return new Coordinaat(letter,cijfer -1);
	}

	public Zet leesBeurt(Scanner regel){
		Coordinaat zetCoordinaat = leesCoordinaat(regel.next().charAt(0),regel.nextInt());
		CoordinaatRij coordinaatRij = new CoordinaatRij(HOOGTE * BREEDTE);
		while(regel.hasNext()){
			coordinaatRij.voegToe(leesCoordinaat(regel.next().charAt(0),regel.nextInt()));
		}
		return new Zet(zetCoordinaat,coordinaatRij);
	}

	public void leesRegel(String input){
		Scanner regel = new Scanner(input);
		boolean wit = leesWitOfZwart(regel.next());
		int denkTijd = regel.nextInt();
		boolean zet = leesZet(regel.next());				
		if(zet){
			beurtRij.voegBeurtToe(new Beurt(zet,wit,denkTijd,leesBeurt(regel)));
		} else{
			beurtRij.voegBeurtToe(new Beurt(zet,wit,denkTijd));
		}
	}
	public void leesBestand(Scanner in){
		while(in.hasNext()){
			leesRegel(in.nextLine());
		}
	}

	public void initialiseerBord(){
		huidigeBeurt = (bordRij.geefAantalBorden() / 2);
		ui.printf("Aantal beurten geladen:%d\n",bordRij.geefAantalBorden());
		laatBordZien(bordRij.geefBord(huidigeBeurt));

	}

	public void start(){
		Scanner in = new Scanner(System.in);
		leesBestand(in);
		verwerkInvoerTotBordRij();
		initialiseerBord();
		wachtOpInvoer();

	}
	public static void main(String[] argv) {
		new Orthello().start();
	}

}
